Skip to content

Tests: Precompile Tests Phase 3 (PLT-372) - #3985

Open
alexander-sei wants to merge 7 commits into
mainfrom
alexanderh/plt-372-precompile-tests-phase-3
Open

Tests: Precompile Tests Phase 3 (PLT-372)#3985
alexander-sei wants to merge 7 commits into
mainfrom
alexanderh/plt-372-precompile-tests-phase-3

Conversation

@alexander-sei

Copy link
Copy Markdown
Contributor

Describe your changes and provide context

Phase 3 of the precompile test refactor (PLT-372), building on the phase 1 framework (#3777) and the phase 2 coverage (#3786).

Phase 2 covered the wasm-free precompiles as they existed then. Since that merged, Generate v6.7 precompiles (#3961), the scoped module authorizations (#3893, #3846) and the module Msg rpc surface (#3825) landed. This phase brings the suite back in line with the deployed interface.

New specs

Precompile Spec Coverage
auth (0x…100D) auth.spec.ts account / accounts / params / nextAccountNumber, LCD parity incl. the nested base account module accounts wrap theirs in
authz (0x…100E) authz.spec.ts grants / granterGrants / granteeGrants; the non-empty fixture is a staking.grantStakingAuthorization, since authz itself cannot grant
evidence (0x…100F) evidence.spec.ts evidence / allEvidence against the module's own list
mint (0x…1012) mint.spec.ts params / minter vs Sei's own /seichain/mint/v1beta1/... routes
params (0x…1013) params.spec.ts params(subspace, key) vs the staking module, plus the unknown/empty subspace reverts
slashing (0x…1014) slashing.spec.ts params / signingInfo / signingInfos, grant + revoke of unjail authorization, and the unjail guards
upgrade (0x…1015) upgrade.spec.ts currentPlan / appliedPlan / upgradedConsensusState / moduleVersions

Existing specs extended

  • bankspendableBalances, totalSupply, params, denomMetadata (via a tokenfactory denom), denomsMetadata (pages until it reaches that denom, so nextKey round-trips).
  • stakinggrantStakingAuthorizationdelegateWithAuthorization → Cosmos-side delegation → revokeStakingAuthorization → reverts; redelegate/undelegateWithAuthorization; and the remaining query surface (validators, validatorDelegations, unbondingDelegation, delegatorDelegations, redelegations, historicalInfo, …).
  • gov — vote and proposal authorizations (grant/voteWithAuthorization/submitProposalWithAuthorization/revoke), plus proposal, proposals, getVote, votes, params, getDeposit, deposits, tallyResult.
  • distributionwithdrawValidatorCommission, the withdraw authorizations, and params, validatorOutstandingRewards, validatorCommission, validatorSlashes, delegationRewards, delegatorValidators, delegatorWithdrawAddress, communityPool.

Framework

  • New addresses on PRECOMPILE_ADDRESSES.
  • cosmosUtils.cosmosRest — an LCD reader for the modules cosmjs does not wrap (mint, params, upgrade, evidence, slashing, authz, auth). Every path was taken from the module's decoded pb.gw.go gateway pattern rather than guessed, and every response field from its proto tag; the API server marshals with OrigName + EmitDefaults, so the reads are snake_case.
  • Bootstrap pool 48 → 80, with the claimPool budget (29) recorded next to it — a non-blocking note from the phase 2 review.

Out of scope, unchanged: wasm-gated flows (wasmd, pointer addCW*, solo), the ibc precompile, and feegrant (0x…1010), which is not registered and whose module was removed in #3958. oracle stays the phase 2 retirement assertion.

Testing performed to validate your change

  • npx tsc --noEmit clean; no lint errors.
  • Every assertion was reviewed against the Go executor and the sei-cosmos keeper behind it rather than against assumption. That pass corrected, among others: historicalInfo pinning an unreachable executor fallback instead of the querier's historical info for height %d not found; nextAccountNumber reading next_account_number where the response field is count; and mint's LCD path, which was three guesses deep with the real route last.
  • It also removed tests that could not fail — a historicalInfo try/catch asserting success in both branches, evidence hardcoding an empty chain in four places, authz index-matching expirations across two independently ordered lists, bank.denomsMetadata asserting only "is an array" — and replaced receipt-only verification of the authorized reward withdrawal with the DelegationRewardsWithdrawn credit its non-authz sibling already pins.

Not yet run against a live cluster. The remaining risk is concentrated in real chain responses, so this wants a make docker-cluster-start + npm run precompile:ci run before merge; I will post the result on this PR.

🤖 Generated with Cursor

Made with Cursor

Extends the precompile suite to the non-wasm precompiles generated for
v6.7 and to the methods added to the existing ones since phase 2, so the
suite tracks the deployed interface rather than the phase 2 snapshot.

New specs: auth (0x100D), authz (0x100E), evidence (0x100F), mint
(0x1012), params (0x1013), slashing (0x1014), upgrade (0x1015).

Existing specs grow to cover the scoped module authorizations and the
query surface they shipped alongside: bank spendableBalances/totalSupply/
params/denomMetadata/denomsMetadata; staking grant/delegate/redelegate/
undelegate/revokeWithAuthorization plus the remaining delegation and
validator queries; gov vote and proposal authorizations plus
proposal/votes/deposits/tally; distribution withdrawValidatorCommission,
the withdraw authorizations, and the validator/delegator queries.

Framework: the new addresses join PRECOMPILE_ADDRESSES, cosmosUtils gains
a cosmosRest LCD reader for the modules cosmjs does not wrap, and the
bootstrap pool grows 48 -> 80 with the claim budget recorded.

Wasm-gated flows (wasmd, pointer addCW*, solo), ibc, and the unregistered
feegrant precompile stay out of scope.

Co-Authored-By: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedSep 13, 2026, 2:06 PM

Comment thread integration_test/precompile_tests/precompiles/gov.spec.ts Outdated
@codecov

codecov Bot commented Aug 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.24%. Comparing base (ba432d8) to head (74ffe8f).

❗ There is a different number of reports uploaded between BASE (ba432d8) and HEAD (74ffe8f). Click for more details.

HEAD has 2 uploads less than BASE
Flag BASE (ba432d8) HEAD (74ffe8f)
sei-db 2 1
sei-db-state-db 1 0
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3985      +/-   ##
==========================================
- Coverage   66.60%   60.24%   -6.37%     
==========================================
  Files        2196     2054     -142     
  Lines      169180   176465    +7285     
==========================================
- Hits       112689   106310    -6379     
- Misses      56350    60428    +4078     
- Partials      141     9727    +9586     
Flag Coverage Δ
sei-db 74.50% <ø> (-0.25%) ⬇️
sei-db-state-db ?

Flags with carried forward coverage won't be shown. Click here to find out more.
see 2209 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

seidroid[bot]
seidroid Bot previously requested changes Aug 23, 2026

@seidroid seidroid Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Phase 3 of the precompile suite is well grounded — every new address, ABI field name, LCD gateway path and Go revert string I spot-checked matches the deployed interface, and the claimPool budget note (29) is accurate. One new assertion in slashing.spec.ts compares two unpinned reads of per-block-mutating signing info and will fail intermittently; two smaller test-strength notes are non-blocking.

Findings: 1 blocking | 2 non-blocking | 3 posted inline

Blockers

  • None at the file/PR level.
  • 1 blocking issue(s) flagged inline on specific lines.

Non-blocking

  • None at the file/PR level.
  • 2 suggestion(s)/nit(s) flagged inline on specific lines.

Comment thread integration_test/precompile_tests/precompiles/slashing.spec.ts
Comment thread integration_test/precompile_tests/precompiles/bank.spec.ts Outdated
Comment thread integration_test/precompile_tests/precompiles/distribution.spec.ts Outdated
slashing: signingInfos and signingInfo were two eth_calls at latest, and
HandleValidatorSignature advances indexOffset for every validator in the
last commit, so a block committing between them failed the equality with
no defect behind it. Both reads now pin the same blockTag, which keeps the
full-struct comparison rather than dropping the moving fields.

bank: totalSupply sends no page limit, so the module default of 100
applies and every factory/... denom this suite mints sorts before usei.
It now walks pages the way denomsMetadata already does instead of
assuming usei is on page one.

distribution: expectCoinArray degenerated to an "is an array" check on an
empty array. It now requires non-empty by default, which the fixture
guarantees for the delegation and validator reads, and communityPool opts
out because sei-cosmos defaults community_tax to 0.

gov: the dispatch section claimed gov has no view methods while a new case
asserted proposal() answers under STATICCALL. The executor dispatches its
queries before the readOnly check, so the label now says transaction
methods, and the duplicate vote rejection that mined the same failing tx
twice is gone.

Co-Authored-By: Cursor <cursoragent@cursor.com>
@alexander-sei

Copy link
Copy Markdown
Contributor Author

Addressed all three of @seidroid's findings, plus the Bugbot note, in f996dac. Each claim was re-verified against the source rather than taken on the review's word.

[blocker] slashing.spec.ts — racing block production. Confirmed: infractions.go:72 advances IndexOffset for every validator in the last commit, so the two eth_calls at latest really could straddle a block. Both reads now pin the same blockTag, following the precedent in distribution.spec.ts. I took the pinning option rather than narrowing asSigningInfo, since that keeps the full-struct equality instead of dropping the moving fields.

[suggestion] bank.spec.ts — single-page assumption. Real latent flake, and self-inflicted: this suite mints a tokenfactory denom on every run, and factory/… sorts before usei. totalSupply now walks pages the way the denomsMetadata test below it does. The supply('usei') bracketing is unchanged, since supply legitimately grows between reads.

[suggestion] distribution.spec.ts — vacuous on empty. expectCoinArray now requires non-empty by default, with a mayBeEmpty opt-out for communityPool — sei-cosmos defaults community_tax to 0% (x/distribution/types/params.go:28), unlike upstream's 2%, so an empty pool is the correct answer there rather than a defect.

One correction to the reasoning, since the conclusion is right but the mechanism isn't: the accruing delegation does not by itself guarantee validatorCommission is non-empty — commission is the operator's cut, so a 0%-rate validator would leave it empty regardless of how healthy the delegation is. What actually guarantees it here is that the devnet's genesis validators are created by seid gentx with no --commission-rate (docker/localnode/scripts/step1_configure_init.sh:58), taking the CLI default of 10%, and DefaultMinCommissionRate is 5% so no validator can drop to zero. I tightened the assertion and recorded that reason.

[Bugbot, low] gov.spec.ts — self-contradicting dispatch section. Also correct. Execute dispatches all eight query methods before the readOnly check, so gov views do answer under STATICCALL and only transaction methods are refused; the stale "gov has no view methods" label is now accurate. The duplicate vote STATICCALL case is removed, so the suite no longer mines the same failing tx twice.

npx tsc --noEmit clean, no lint errors. Still not run against a live cluster — that remains the gate before merge and I'll post the result here.

alexander-sei and others added 2 commits August 26, 2026 15:55
The precompile suite read its Cosmos-side oracle from the LCD at
localhost:1317. No container in the integration cluster publishes that
port, so every cosmosRest call was refused and 15 tests failed.

Replace cosmosRest with utils/moduleQueries.ts, which calls each module's
protobuf Query service through abci_query on the Tendermint RPC port the
suite already uses. That routes through the same handlers the node's gRPC
server exposes, so the answers are identical and no cluster port changes.

stakingHistoricalInfo now separates the module's not-found answer from a
transport failure. The old .catch(() => undefined) read a refused
connection as "this height is not retained" and then asserted the
precompile must revert, which is what turned a connection failure into a
"tx must fail" assertion.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@alexander-sei
alexander-sei marked this pull request as draft August 26, 2026 15:45
@alexander-sei
alexander-sei marked this pull request as ready for review August 27, 2026 11:21

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6c8f42e. Configure here.

: null;
},
{ timeoutMs: 8_000, intervalMs: 200, label: 'validatorUnbondingDelegations' },
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unbonding queries outlive unbonding window

Medium Severity

After undelegate, this test sequentially waits up to 8s for unbondingDelegation and another 8s for validatorUnbondingDelegations. Devnet unbonding_time is 10s, so the second poll can run after the entry has matured and been removed, causing a flake rather than catching a precompile bug.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6c8f42e. Configure here.

@alexander-sei

Copy link
Copy Markdown
Contributor Author

@seidroid review

@seidroid seidroid Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Phase 3 of the precompile suite holds up under spot-checking: every new address, revert string, ABI field name and proto route I verified matches the deployed interface, and all three findings from the previous review are genuinely fixed. Only a small documentation gap remains.

Findings: 0 blocking | 1 non-blocking | 0 posted inline

Blockers

  • None at the file/PR level.

Non-blocking

  • [suggestion] README.md's directory tree (lines 106-113) enumerates every file under utils/ but was not updated for the new utils/moduleQueries.ts, even though the PR does touch this README. That file is now the suite's primary Cosmos-side parity oracle (auth, authz, bank params, distribution, evidence, mint, slashing, staking historical info, upgrade) and is the first thing a new spec author needs to find. Add a line such as │ ├── moduleQueries.ts # abci_query parity oracle for modules cosmjs does not wrap. Relatedly, the PR description still describes this as cosmosUtils.cosmosRest, an LCD reader over SEI_REST — the implementation landed as raw abci_query through the shared Tendermint client instead, and SEI_REST was removed; worth correcting the description before merge so the commit message does not contradict the code.

@seidroid
seidroid Bot dismissed their stale review September 13, 2026 14:16

Superseded: latest AI review found no blocking issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant